package cn.coufran.springboot.starter.auth.impl.token.config;

import cn.coufran.springboot.starter.auth.AuthUser;
import cn.coufran.springboot.starter.auth.AuthUserManager;
import cn.coufran.springboot.starter.auth.impl.token.*;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.util.StringUtils;
import org.springframework.web.context.annotation.RequestScope;

import java.util.ArrayList;
import java.util.List;

/**
 * Session权限拦截配置
 * @author Coufran
 * @version 1.1.0
 * @since 1.0.0
 */
public class TokenAuthConfig {
    @Bean
    @ConditionalOnMissingBean(KeyStore.class)
    public KeyStore keyStore(
            @Value("${coufran.auth.token.key:}") String keyPath) {
        if (StringUtils.hasText(keyPath)) {
            return new FileKeyStore(keyPath);
        } else {
            return new FileKeyStore();
        }
    }

    /**
     * Token注册机
     * @return Token注册机
     */
    @Bean
    @ConditionalOnMissingBean(TokenRegister.class)
    public TokenRegister tokenRegister(KeyStore keyStore) {
        byte[] key = keyStore.load();
        if (key != null) {
            return new JjwtTokenRegister(key);
        } else {
            JjwtTokenRegister tokenRegister = new JjwtTokenRegister();
            key = tokenRegister.getKey();
            keyStore.save(key);
            return tokenRegister;
        }
    }

    /**
     * Payload解析器
     * @return Payload解析器
     */
    @Bean
    @ConditionalOnMissingBean(name = "tokenPayloadConverters")
    public List<TokenPayloadConverter<?>> tokenPayloadConverters() {
        List<TokenPayloadConverter<?>> tokenPayloadConverters = new ArrayList<>(1);
        tokenPayloadConverters.add(new PojoJsonTokenPayloadConverter());
        return tokenPayloadConverters;
    }

    /**
     * Refresh Token存储
     * @return Refresh Token存储
     */
    @Bean
    @ConditionalOnMissingBean(RefreshTokenRepository.class)
    public RefreshTokenRepository refreshTokenRepository() {
        return new LocalMapRefreshTokenRepository();
    }

    /**
     * 权限上下文
     * @param tokenRegister Token注册机
     * @param tokenPayloadConverters Payload转换器
     * @param refreshTokenRepository  Refresh Token存储
     * @return 权限上下文
     */
    @Bean
    public AuthUserManager authUserManager(
            TokenRegister tokenRegister,
            List<TokenPayloadConverter<?>> tokenPayloadConverters,
            RefreshTokenRepository refreshTokenRepository) {
        return new TokenAuthUserManager(tokenRegister, tokenPayloadConverters, refreshTokenRepository);
    }

    /**
     * 权限用户
     * @param request Request对象
     * @param authUserManager 权限上下文
     * @param <U> 权限用户承载的数据类型
     * @return 权限用户
     */
    @Bean
    @RequestScope
    public <U> AuthUser<U> authUser(HttpServletRequest request, AuthUserManager authUserManager) {
        String token = request.getHeader("Token");
        return authUserManager.getAuthUser(new TokenCertificate(token));
    }

}
